#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <fstream>

#include "Common.hpp"
#include "Log.hpp"
using namespace LogModule;

const std::string Sep = "\r\n";
const std::string LineSep = " ";
const std::string HeaderLineSep = ": ";
const std::string BlankLine = Sep;
const std::string defaulthomepage = "wwwroot";
const std::string http_version = "HTTP/1.0";
const std::string page404 = "wwwroot/404.html";
const std::string firstpage = "index.html";

class HttpRequest
{
public:
	HttpRequest()
	{
	}

	bool IsHasArgs()
	{
		return _isexec;
	}

	void Deserilalize(std::string &request_str) // 反序列化
	{
		if (ParseOneLine(request_str, &_req_line, Sep)) // 解析第一行 http://118.190.159.205:8080/login?username=111&password=111
		//同学对于这样的url你是怎么处理的
		{
			// 提取请求行的详细字段
			ParseRequestLine(_req_line, LineSep);
			ParseHeader(request_str);
			_body = request_str;

			// 分析请求中，是否含有参数
			if (_method == "POST")
			{
				_isexec = true; // 参数在正文
				_args = _body;
				_path = _uri;
				LOG(LogLevel::DEBUG) << "_path: " << _path;
				LOG(LogLevel::DEBUG) << "_args: " << _args;
			}
			else if (_method == "GET")
			{
				auto pos = _uri.find("?");
				if (pos != std::string::npos) //这里是不等于
				{
					_isexec = true;
					// /login?name=zhangsan&passwd=123456
					_path = _uri.substr(0, pos);
					_args = _uri.substr(pos + 1);
					LOG(LogLevel::DEBUG) << "_path: " << _path;
					LOG(LogLevel::DEBUG) << "_args: " << _args;
				}
			}
		}
	}
	~HttpRequest()
	{
	}

	void Print()
	{
		std::cout << "_method " << _method << std::endl;
		std::cout << "_uri " << _uri << std::endl;
		std::cout << "_version " << _version << std::endl;

		for (auto &kv : _headerkv)
		{
			std::cout << kv.first << "# " << kv.second << std::endl;
		}
		std::cout << "_blank_line " << _blank_line << std::endl;
		std::cout << "_body " << _body << std::endl;
	}

	std::string Uri()
	{
		return _uri;
	}

	std::string GetContent(const std::string path)
	{
		std::string content;
		std::ifstream in(path, std::ios::binary); // 这里打开的是一个目录导致的"wwwroot/"
		if (!in.is_open())
			return std::string();
		in.seekg(0, in.end);
		int filesize = in.tellg();
		in.seekg(0, in.beg);

		content.resize(filesize);
		in.read((char *)content.c_str(), filesize);

		in.close();
		return content;

		// std::string content;
		// std::ifstream in(_uri);
		// std::cout << "uri: "<< _uri << std::endl;
		// if(!in.is_open()) return std::string();
		// std::string line;
		// while(std::getline(in,line))
		// {
		// 	content += line;
		// }
		// in.close();
		// return content;
	}
	std::string SetUri(const std::string newuri)
	{
		_uri = newuri;
		return _uri;
	}

	// _uri -> wwwroot/index.html   wwwroot/image/1.jpg
	std::string Suffix() // 获取后缀
	{
		auto pos = _uri.rfind(".");
		if (pos == std::string::npos)
			return std::string(".html");
		else
			return _uri.substr(pos);
	}

	std::string Path() { return _path; }
	std::string Args() { return _args; }

private:
	void ParseRequestLine(std::string &line, const std::string sep)
	{
		(void)sep;
		std::stringstream ss(_req_line);
		ss >> _method >> _uri >> _version; // _method GRE  _uri /index.html  _version HTTP/1.1

		// if (_uri == "/")
		// {
		// 	_uri = defaulthomepage + _uri + firstpage;
		// }
		// else
		// {
		// 	_uri = defaulthomepage + _uri;
		// }
	}

	bool ParseHeaderKV()
	{
		std::string key, value;
		for (auto &header : _req_header)
		{
			// 分割字符串
			if (SplitString(header, HeaderLineSep, &key, &value))
			{
				_headerkv.insert(std::make_pair(key, value));
			}
		}
		return true;
	}
	bool ParseHeader(std::string &request_str)
	{
		std::string line;
		while (true)
		{
			bool r = ParseOneLine(request_str, &line, Sep);
			if (r && line.empty())
			{
				_req_header.push_back(line);
				break;
			}
			else if (r && line.empty())
			{
				_blank_line = Sep;
				break;
			}
			else
				return false;
		}
		ParseHeaderKV();
		return true;
	}

private:
	std::string _req_line;				  // 请求行
	std::vector<std::string> _req_header; // 请求报头
	std::string _blank_line;			  // 空行
	std::string _body;					  // 请求正文
	std::string _path;
	std::string _args;

	// 在反序列化的过程中，细化我们解析出来的字符串
	std::string _method;  // 方法
	std::string _uri;	  // 统一资源标识符
	std::string _version; // 版本
	std::unordered_map<std::string, std::string> _headerkv;

	bool _isexec = false; // 是否需要服务器执行
};

// 对于http，任何请求都要有应答
class HttpResponse
{
public:
	HttpResponse()
		: _version(http_version), _blank_line(Sep)
	{
	}
	void Bulid(HttpRequest &req)
	{
		// std::string uri = req.Uri(); // 测试重定向
		// if (uri.back() == '/')
		// {
		// 	_status_code = 302;
		// 	_status_desc = Code_to_Desc(_status_code);
		// 	SetHeader("Location", "https://im.qq.com/index/");
		// 	for (auto &header : _header_kv)
		// 	{
		// 		_resp_header.push_back(header.first + HeaderLineSep + header.second);
		// 	}
		// 	return;
		// }

		std::string uri = defaulthomepage + req.Uri();
		if (uri.back() == '/')
		{
			uri += firstpage;
			req.SetUri(uri);
		}

		_content = req.GetContent(uri);
		if (_content.empty())
		{
			// 用户请求的资源并不存在
			_status_code = 404;
			req.SetUri(page404);
			_content = req.GetContent(page404);
		}
		else
		{
			_status_code = 200;
		}
		_status_desc = Code_to_Desc(_status_code);

		if (!_content.empty())
		{
			SetHeader("Content-Length", std::to_string(_content.size()));
		}

		std::string mime_type = Suffix_to_Desc(req.Suffix());
		SetHeader("Content-Type", mime_type);

		_body = _content;
	}

	void Serialize(std::string *resp_str) // 序列化
	{
		for (auto &header : _header_kv)
		{
			_resp_header.push_back(header.first + HeaderLineSep + header.second);
		}

		_resp_line = _version + LineSep + std::to_string(_status_code) + LineSep + _status_desc + Sep;

		// 序列化
		*resp_str = _resp_line;
		for (auto &line : _resp_header)
		{
			*resp_str += (line + Sep);
		}
		*resp_str += _blank_line;
		*resp_str += _body;
	}
	void SetCode(int code)
	{
		_status_code = code;
		_status_desc = Code_to_Desc(_status_code);
	}

	void SetBody(const std::string &body)
	{
		_body = body;
	}

	void SetHeader(const std::string &k, const std::string &v)
	{
		_header_kv[k] = v;
	}

	~HttpResponse()
	{
	}

private:
	std::string Code_to_Desc(int code)
	{
		switch (code)
		{
		case 200:
			return "OK";
		case 404:
			return "Not Found";
		case 301:
			return "Moved Permanently";
		case 302:
			return "Found";
		default:
			return std::string();
		}
	}

	std::string Suffix_to_Desc(const std::string &suffix)
	{
		if (suffix == ".html")
			return "text/html";
		else if (suffix == ".jpg")
			return "application/x-jpg";
		else
			return "text/html";
	}

private:
	// 必备的应答要素
	std::string _version;	  // 版本
	int _status_code;		  // 状态码
	std::string _status_desc; // 状态码的描述
	std::string _content;
	std::unordered_map<std::string, std::string> _header_kv;

	std::string _resp_line;				   // 状态行
	std::vector<std::string> _resp_header; // 响应报头
	std::string _blank_line;			   // 空行
	std::string _body;					   // 响应正文
};